﻿using System;
using l1cs.server.model.Instance;
using l1cs.server.model.map;

namespace l1cs.server.model
{
    [Serializable()]
    public class L1Object
    {
        private int _id = 0;

        /// <summary>
        /// オブジェクトが存在するマップのマップIDを返す。
        /// </summary>
        /// <returns>マップID</returns>
        public short getMapId()
        {/*TTOK*/
            return (short)_loc.getMap().getId();
        }

        /// <summary>
        /// オブジェクトが存在するマップのマップIDを設定する。
        /// </summary>
        /// <param name="mapId">マップID</param>
        public void setMap( short mapId )
        {/*TTOK*/
            _loc.setMap( L1WorldMap.getInstance().getMap( mapId ) );
        }

        /// <summary>
        /// オブジェクトが存在するマップを保持するL1Mapオブジェクトを返す。
        /// </summary>
        /// <returns></returns>
        public L1Map getMap()
        {
            return _loc.getMap();
        }

        /// <summary>
        /// オブジェクトが存在するマップを設定する。
        /// </summary>
        /// <param name="map">オブジェクトが存在するマップを保持するL1Mapオブジェクト</param>
        /// <exception cref="NullReferenceException">NullReferenceException</exception>
        public void setMap( L1Map map )
        {
            if ( map == null )
            {
                throw new NullReferenceException();
            }
            _loc.setMap( map );
        }

        /// <summary>
        /// オブジェクトを一意に識別するIDを返す。
        /// </summary>
        /// <returns>オブジェクトID</returns>
        public int getId()
        {
            return _id;
        }

        /// <summary>
        /// オブジェクトを一意に識別するIDを設定する。
        /// </summary>
        /// <param name="id">オブジェクトID</param>
        public void setId( int id )
        {
            _id = id;
        }

        /// <summary>
        /// オブジェクトが存在する座標のX値を返す。
        /// </summary>
        /// <returns>座標のX値</returns>
        public int getX()
        {/*TTOK*/
            return _loc.getX();
        }

        /// <summary>
        /// オブジェクトが存在する座標のX値を設定する。
        /// </summary>
        /// <param name="x">座標のX値</param>
        public void setX( int x )
        {/*TTOK*/
            _loc.setX( x );
        }

        /// <summary>
        /// オブジェクトが存在する座標のY値を返す。
        /// </summary>
        /// <returns>座標のY値</returns>
        public int getY()
        {/*TTOK*/
            return _loc.getY();
        }

        /// <summary>
        /// オブジェクトが存在する座標のY値を設定する。
        /// </summary>
        /// <param name="y">座標のY値</param>
        public void setY( int y )
        {/*TTOK*/
            _loc.setY( y );
        }

        private L1Location _loc = new L1Location();

        /// <summary>
        /// オブジェクトが存在する位置を保持する、L1Locationオブジェクトへの参照を返す。
        /// </summary>
        /// <returns>座標を保持する、L1Locationオブジェクトへの参照</returns>
        public L1Location getLocation()
        {
            return _loc;
        }

        public void setLocation( L1Location loc )
        {
            _loc.setX( loc.getX() );
            _loc.setY( loc.getY() );
            _loc.setMap( loc.getMapId() );
        }

        public void setLocation( int x, int y, int mapid )
        {
            _loc.setX( x );
            _loc.setY( y );
            _loc.setMap( mapid );
        }

        /// <summary>
        /// 指定されたオブジェクトまでの直線距離を返す。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public double getLineDistance( L1Object obj )
        {
            return this.getLocation().getLineDistance( obj.getLocation() );
        }

        /// <summary>
        /// 指定されたオブジェクトまでの直線タイル数を返す。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int getTileLineDistance( L1Object obj )
        {
            return this.getLocation().getTileLineDistance( obj.getLocation() );
        }

        /// <summary>
        /// 指定されたオブジェクトまでのタイル数を返す。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int getTileDistance( L1Object obj )
        {
            return this.getLocation().getTileDistance( obj.getLocation() );
        }

        /// <summary>
        /// オブジェクトがプレイヤーの画面内に入った(認識された)際に呼び出される。
        /// </summary>
        /// <param name="perceivedFrom">このオブジェクトを認識したPC</param>
        public virtual void onPerceive( L1PcInstance perceivedFrom ) { }

        /// <summary>
        /// オブジェクトへのアクションが発生した際に呼び出される。
        /// </summary>
        /// <param name="actionFrom">アクションを起こしたPC</param>
        virtual public void onAction( L1PcInstance actionFrom ) { }

        /// <summary>
        /// オブジェクトが話しかけられたとき呼び出される。
        /// </summary>
        /// <param name="talkFrom">話しかけたPC</param>
        virtual public void onTalkAction( L1PcInstance talkFrom ) { }
    }
}
